package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseServiceImpl;
import top.lixunda.ecommerce.server.business.api.entity.cache.CacheUser;
import top.lixunda.ecommerce.server.good.api.entity.db.SimpleReviewDetailDO;
import top.lixunda.ecommerce.server.good.api.entity.db.SimpleReviewPraiseDO;
import top.lixunda.ecommerce.server.good.mapper.SimpleReviewPraiseMapper;
import top.lixunda.ecommerce.server.good.service.ISimpleReviewDetailService;
import top.lixunda.ecommerce.server.good.service.ISimpleReviewPraiseService;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 'commerce_goods.order_detail' is not BASE TABLE 服务实现类
 * </p>
 *
 * @author Xumda
 * @since 2020-01-06
 */
@Service
public class SimpleReviewPraiseServiceImpl
        extends BaseServiceImpl<SimpleReviewPraiseMapper, SimpleReviewPraiseDO>
        implements ISimpleReviewPraiseService {

    private final ISimpleReviewDetailService simpleReviewDetailService;

    @Autowired
    public SimpleReviewPraiseServiceImpl(ISimpleReviewDetailService simpleReviewDetailService) {
        this.simpleReviewDetailService = simpleReviewDetailService;
    }

    /**
     * 根据简单评论的id获取当前评论的点赞数量
     *
     * @param id 评论id
     * @return 点赞次数
     */
    @Override
    public Integer queryPraiseCountById(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("评论id不能为空");
        }
        SimpleReviewDetailDO simpleReviewDetailDO = simpleReviewDetailService.getOne(
                new LambdaQueryWrapper<SimpleReviewDetailDO>()
                        .eq(SimpleReviewDetailDO::getId, id), false);
        if (ObjectValidators.isEmpty(simpleReviewDetailDO)) {
            throw getAppException("评论不存在");
        }
        return simpleReviewDetailDO.getPraise();
    }

    /**
     * 根据多个评论id获取多个评论的点赞次数
     *
     * @param ids 评论id的列表
     * @return 键值对，键为评论id，值为评论点赞次数
     */
    @Override
    public Map<Integer, Integer> queryPraiseCountByIds(List<Integer> ids) {
        if (ObjectValidators.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        List<SimpleReviewDetailDO> simpleReviewDetailDoList = simpleReviewDetailService.list(
                new LambdaQueryWrapper<SimpleReviewDetailDO>()
                        .select(SimpleReviewDetailDO::getPraise)
                        .in(SimpleReviewDetailDO::getId, ids));
        Map<Integer, Integer> map = new HashMap<>(ids.size());
        for (SimpleReviewDetailDO simpleReviewDetailDO : simpleReviewDetailDoList) {
            map.put(simpleReviewDetailDO.getId(), simpleReviewDetailDO.getPraise());
        }
        return map;
    }

    /**
     * 对某个商品的某个简单评论进行一次点赞
     *
     * @param reviewId 评论id
     * @return 点赞后的该评论的点赞次数
     */
    @Override
    public Integer addPraiseById(Integer reviewId) {
        if (ObjectValidators.isEmpty(reviewId)) {
            throw getAppException("评论id不能为空");
        }
        CacheUser userInfoDO = currentUserCacheNotNull();
        int count = this.count(new LambdaQueryWrapper<SimpleReviewPraiseDO>()
                .eq(SimpleReviewPraiseDO::getSimpleReviewId, reviewId)
                .eq(SimpleReviewPraiseDO::getUserId, userInfoDO.getAccount()));
        if(count <= 0){
            SimpleReviewPraiseDO simpleReviewPraiseDO = new SimpleReviewPraiseDO();
            simpleReviewPraiseDO.setSimpleReviewId(reviewId);
            simpleReviewPraiseDO.setUserId(userInfoDO.getAccount());
            simpleReviewPraiseDO.setUserName(userInfoDO.getFirstName() + userInfoDO.getLastName());
            simpleReviewPraiseDO.setTime(LocalDateTime.now());
            boolean success = this.save(simpleReviewPraiseDO);
            if (!success) {
                throw getAppException("保存失败");
            }
        }
        return queryPraiseCountById(reviewId);
    }

    /**
     * 取消对某个评论的点赞
     *
     * @param reviewId 评论id
     * @return 取消点赞后的该评论的点赞次数
     */
    @Override
    public Integer cancelPraiseById(Integer reviewId) {
        if (ObjectValidators.isEmpty(reviewId)) {
            throw getAppException("评论编号不能为空");
        }
        CacheUser userInfoDO = currentUserCacheNotNull();
        this.remove(new LambdaUpdateWrapper<SimpleReviewPraiseDO>()
                .eq(SimpleReviewPraiseDO::getSimpleReviewId, reviewId)
                .eq(SimpleReviewPraiseDO::getUserId, userInfoDO.getAccount()));
        return this.count(new LambdaQueryWrapper<SimpleReviewPraiseDO>()
                .eq(SimpleReviewPraiseDO::getSimpleReviewId, reviewId));
    }

    /**
     * 当前登陆用户是否对某个评论进行点赞
     *
     * @param reviewId 评论id
     * @return 是否进行点赞
     */
    @Override
    public Boolean currentPraiseFlagById(Integer reviewId) {
        if (ObjectValidators.isEmpty(reviewId)) {
            throw getAppException("评论编号不能为空");
        }
        CacheUser userInfoDO = currentUserCacheNotNull();
        SimpleReviewPraiseDO simpleReviewPraiseDO = this.getOne(
                new LambdaQueryWrapper<SimpleReviewPraiseDO>()
                        .eq(SimpleReviewPraiseDO::getSimpleReviewId, reviewId)
                        .eq(SimpleReviewPraiseDO::getUserId, userInfoDO.getAccount()),
                false);
        return ObjectValidators.isNotEmpty(simpleReviewPraiseDO);
    }

    /**
     * 当前登陆用户是否对某些评论进行点赞
     *
     * @param reviewIds 评论id列表
     * @return 是否进行点赞，键值对，键为评论编号，值为是否点赞
     */
    @Override
    public Map<Integer, Boolean> currentPraiseFlagByIds(List<Integer> reviewIds) {
        if (ObjectValidators.isEmpty(reviewIds)) {
            throw getAppException("评论编号不能为空");
        }
        CacheUser userInfoDO = currentUserCacheNotNull();
        if (ObjectValidators.isEmpty(userInfoDO)) {
            return reviewIds.stream()
                    .distinct()
                    .collect(Collectors.toMap(item -> item, item -> false));
        }
        List<SimpleReviewPraiseDO> list = this.list(
                new LambdaQueryWrapper<SimpleReviewPraiseDO>()
                        .in(SimpleReviewPraiseDO::getSimpleReviewId, reviewIds)
                        .eq(SimpleReviewPraiseDO::getUserId, userInfoDO.getAccount()));
        Map<Integer, Boolean> resultMap = reviewIds.stream()
                .collect(Collectors.toMap(item -> item, item -> false));
        list.forEach(item -> resultMap.put(item.getSimpleReviewId(), true));
        return resultMap;
    }

}
